/*
 * MBGame.java
 * 
 *  author: Daniel Rudigier
 *    date: 02.12.2008
 * 
 * 
 */
package at.momberban2.me.game;

import at.syncme.aspects.algorithm.DummySync;
import at.syncme.aspects.network.DummyNW;
import at.syncme.framework.Event;
import at.syncme.framework.Game;
import at.syncme.framework.GameState;
import at.syncme.framework.legacy.WrapperCache;

/**
 * the momberban game
 * 
 * @author Daniel Rudigier
 */
public class M2Game extends Game {
    private static final M2ResourceManager MGR = (M2ResourceManager) M2ResourceManager
            .getInstance();

    private static final String M1_UUID = "a00914d6469143dcb1fb85fd4a994594";

    private static final String M2_UUID = "a00914d6469143dcb1fb85fd4a994594";

    private static final String GAME_NAME = "MomberBan2";

    protected M2GameState m2state;
    
    protected Byte me;

    /**
     * constructor
     * 
     * @param gs
     */
    public M2Game() {
        super(new M2GameState(), new DummySync(new DummyNW()));
        
        // LockStep.getInstance(BTNetwork.getInstance(GAME_NAME, M2_UUID))
        this.m2state = (M2GameState) gs;
    }
    
    /**
     * override
     *
     * @see at.syncme.framework.Game#setGs(at.syncme.framework.GameState)
     */
    public void setGs(GameState gs) {
        super.setGs(gs);
        this.m2state = (M2GameState) gs;
    }

    /**
     * override
     * 
     * @see at.syncme.framework.cs.CSGame#setupEvent(at.syncme.framework.Event)
     */
    public void setupEvent(final Event e) {
        if (e.getId() == Event.SETUP_SERVER) {
            // prepare as server
            this.m2state.setup(MGR.getMaps()[0]);
            this.me = this.m2state.newPlayer();
            this.eventHandler = new M2Server(this);
        } else if (e.getId() == Event.SETUP_CLIENT) {
            // prepare as client
            this.m2state.setup(null);
            this.eventHandler = new M2Client(this);
        } else if (e.getId() == M2Event.SETUP_MAP) {
            // TODO: map decode
            this.m2state.setMap(MGR.getMaps()[0]);
        } else if (e.getId() == Event.SETUP_START) {
            gameEvent(e);
        } else {
            // this.eventHandler = null;
        }
    }

    /**
     * override
     * 
     * @see at.syncme.framework.Game#gameEvent(at.syncme.framework.Event)
     */
    public void gameEvent(Event e) {
        if (this.algo == null) {
            throw new IllegalStateException("sync. algorithm is null");
        }
        if (this.eventHandler == null) {
            throw new IllegalStateException("event handler is null");
        }
        
        final short id = e.getId();

        System.out.println("game event: " + e);

        if (id == Event.SETUP_START || id == Event.GAME_PREPARE) {
            // prepare the game
            this.m2state.prepare();
        } else if (id == Event.GAME_RUN) {
            System.out.println("<< game started >>");
            start();
        } else if (id == M2Event.MOVE_DOWN
                || id == M2Event.MOVE_UP
                || id == M2Event.MOVE_LEFT
                || id == M2Event.MOVE_RIGHT
                || id == M2Event.MOVE_STOP) {
            this.m2state.playerMove(getPlayer(e), (byte) e.getId());
        } else if (id == M2Event.BOMB_PLANTED) {
            this.m2state.plantBomb(getPlayer(e));
        } else if (id == Event.PLAYER_DISCONNECTED) {
            playerLeft(e);
        } else {
            // not understood
        }
                
        System.out.println("threads: " + Thread.activeCount());
        
        // call the client-server specific event handler
        eventHandler.gameEvent(e);
    }
    
    /**
     * Elvis has left the building
     * 
     * @param e
     */
    private void playerLeft(Event e) {
        this.m2state.playerLeft(getPlayer(e));
    }

    /**
     * decode the player from an event. 
     * 
     * @param e
     * @return
     * 
     */
    public Byte getPlayer(Event e) {
        Byte id = WrapperCache.valueOf((byte)(e.getOrigin() + 2));
        return id;
    }
    
    /**
     * @return me
     */
    public Byte getMe() {
        return me;
    }

    /**
     * @param me
     *            to set
     */
    public void setMe(Byte me) {
        this.me = me;
    }

    /**
     * override
     * 
     * @see at.syncme.framework.Game#end()
     */
    protected void end() {
        System.out.println("game finished");
    }

}
